#!/bin/env python

"""
Script to process data from soil matric pressure experiment and import
into a Howl feed.

$ python watermark.py --help
Usage: watermark.py [options]

Options:
  -h, --help            show this help message and exit
  -e EMAIL, --email=EMAIL
                        Your Google mail address
  -p PASSWORD, --password=PASSWORD
                        Your Google mail password
  -c COMMAND, --command=COMMAND
                        Howl command to execute
$

Copyright (C) Sarah Mount, 2009.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have rceeived a copy of the GNU General Public License
along with this program; if not, write to the Free Software
"""

import sys
sys.path.append('../../scripts/')

import howl
import math
import MySQLdb
import sys
import time


__author__ = 'Sarah Mount <s.mount@wlv.ac.uk>'
__date__ = '21 November 2009'


def getdata(dbhost='localhost', dbuser='root',
            dbpassword='f00bar', dbdb='soilcollector'):
    """Retrieve soil matric pressure data from database.

    Return as a list of tuples.
    """
    try:
        conn = MySQLdb.connect(host=dbhost,
                               user=dbuser,
                               passwd=dbpassword,
                               db=dbdb)
        cursor = conn.cursor()
        # Get DB data.
        sql = "SELECT * FROM SoilMoisture;"
        cursor.execute(sql)
        res = []
        while True:
            try:
                results = cursor.fetchmany(1000)
                res.append(results[0])
            except:
                break
        # Close DB connection.
        cursor.close()
        conn.close()
        return res
    except Exception, e:
        print ('Could not read from database: ' +  str(sys.exc_info()[1]))

def rh_to_kpa(t_c, rh, kPa):
    """Convert a relative humidity to soil matric pressure.

    @param t_c Temperature in Centigrade.
    @param rh Relative humidity.
    @param kPa Soil matric pressure (taken with a specialist sensor).

    @return a tuple containing the matric pressure estimated from the
    RH value and an 'error' measure, as the percentage difference
    between the estimated kPa and the measured matric pressure passed
    into this function in the agument list.
    """
    R = 8.314          # J mol^-1 K^-1
    V_w = 18           # mL / mol
    t_k = t_c - 273.15 # Temperature in Kelvin
    estimated = abs((R * t_c / V_w) * math.log(rh / 100.0)) # kPa
    error = abs(estimated - kPa) / kPa * 100.0              # %
    return (estimated, error)

def sendsoil(email, password):
    """Send soil data from the MySQL database to Howl.

    Calls getdata().

    @param email User's Google email address.
    @param password User's Google account password.
    """
    def execute(command):
        """Execute a given Howl command.
        
        @param command Howl command as a string.
        """
        print command
        try:
            howl.run_command(email, password, command)
        except:
            pass
    data = getdata()
    execute('delete Watermark')
    execute('create Watermark temp Centigrade rh percent estimated kPa watermark kPa error percent')
    execute('register Watermark pot1 52.586 -2.115')
    execute('register Watermark pot2 52.586 -2.115')
    cmd = 'insert Watermark %s temp %g rh %g estimated %g watermark %g error %g'
    for datum in data:
        # pot1
        est, err = rh_to_kpa(float(datum[1]), float(datum[2]), float(datum[3]))
        execute(cmd %
                ('pot1', float(datum[1]), float(datum[2]), est, 
                 float(datum[3]), err))
        # pot2
        est, err = rh_to_kpa(float(datum[4]), float(datum[5]), float(datum[6]))
        execute(cmd %
                ('pot2', float(datum[4]), float(datum[5]), est,
				 float(datum[6]), err))
        time.sleep(30)
    return


if __name__ == '__main__':

    from optparse import OptionParser

    parser = OptionParser()
    parser.add_option('-e', '--email', dest='email', 
                      action='store', type='string',
                      help='Your Google mail address')    
    parser.add_option('-p', '--password', dest='password', 
                      action='store', type='string',
                      help='Your Google mail password')    
    parser.add_option('-c', '--command', dest='command', 
                      action='store', type='string',
                      help='Howl command to execute')    

    (options, args) = parser.parse_args()
    
    sendsoil(options.email, options.password)
